1   /*
2    * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
3    *
4    * Redistribution and use in source and binary forms, with or without
5    * modification, are permitted provided that the following conditions
6    * are met:
7    *
8    *   - Redistributions of source code must retain the above copyright
9    *     notice, this list of conditions and the following disclaimer.
10   *
11   *   - Redistributions in binary form must reproduce the above copyright
12   *     notice, this list of conditions and the following disclaimer in the
13   *     documentation and/or other materials provided with the distribution.
14   *
15   *   - Neither the name of Oracle nor the names of its
16   *     contributors may be used to endorse or promote products derived
17   *     from this software without specific prior written permission.
18   *
19   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
20   * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21   * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22   * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23   * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24   * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25   * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26   * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27   * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28   * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29   * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30   */
31  
32  package j2dbench;
33  
34  import java.awt.BorderLayout;
35  import java.awt.Toolkit;
36  import java.awt.Color;
37  import java.awt.event.ItemEvent;
38  import java.awt.event.ItemListener;
39  import javax.swing.JComponent;
40  import javax.swing.JCheckBox;
41  import javax.swing.JComboBox;
42  import javax.swing.JTextField;
43  import javax.swing.JPanel;
44  import javax.swing.JLabel;
45  import javax.swing.JList;
46  import javax.swing.event.ListSelectionEvent;
47  import javax.swing.event.ListSelectionListener;
48  import javax.swing.text.BadLocationException;
49  import javax.swing.text.PlainDocument;
50  import javax.swing.text.AttributeSet;
51  import javax.swing.border.LineBorder;
52  import java.io.PrintWriter;
53  import java.util.NoSuchElementException;
54  import java.util.StringTokenizer;
55  
56  public abstract class Option extends Node implements Modifier {
57      public Option(Group parent, String nodeName, String description) {
58          super(parent, nodeName, description);
59      }
60  
61      public abstract boolean isDefault();
62  
63      public void modifyTest(TestEnvironment env, Object val) {
64          env.setModifier(this, val);
65      }
66  
67      public void restoreTest(TestEnvironment env, Object val) {
68          env.removeModifier(this);
69      }
70  
71      public abstract String getValString();
72  
73      public String getValString(Object v) {
74          return v.toString();
75      }
76  
77      public String getOptionString() {
78          return getTreeName()+"="+getValString();
79      }
80  
81      public String getOptionString(Object value) {
82          return getTreeName()+"="+getValString(value);
83      }
84  
85      public String getAbbreviatedModifierDescription(Object value) {
86          return getNodeName()+"="+getValString(value);
87      }
88  
89      public String getModifierValueName(Object val) {
90          return getValString(val);
91      }
92  
93      public String setOption(String key, String value) {
94          if (key.length() != 0) {
95              return "Option name too specific";
96          }
97          return setValueFromString(value);
98      }
99  
100     public abstract String setValueFromString(String value);
101 
102     public void write(PrintWriter pw) {
103         //if (!isDefault()) {
104             pw.println(getOptionString());
105         //}
106     }
107 
108     public String toString() {
109         return "Option("+getOptionString()+")";
110     }
111 
112     public static class Toggle extends Option {
113         public static final int Off = 0;
114         public static final int On = 1;
115         public static final int Both = 2;
116 
117         private static final String valnames[] = {"Off", "On", "Both"};
118         private static final Boolean valuelist[][] = {
119             BooleanIterator.FalseList,
120             BooleanIterator.TrueList,
121             BooleanIterator.FalseTrueList,
122         };
123 
124         int defaultvalue;
125         int value;
126         JPanel jp;
127         JComboBox jcb;
128 
129         public Toggle(Group parent, String nodeName, String description,
130                       int defaultvalue)
131         {
132             super(parent, nodeName, description);
133             if (defaultvalue != Off &&
134                 defaultvalue != On &&
135                 defaultvalue != Both)
136             {
137                 throw new IllegalArgumentException("bad default");
138             }
139             this.defaultvalue = this.value = defaultvalue;
140         }
141 
142         public void restoreDefault() {
143             if (value != defaultvalue) {
144                 value = defaultvalue;
145                 updateGUI();
146             }
147         }
148 
149         public void updateGUI() {
150             if (jcb != null) {
151                 jcb.setSelectedIndex(value);
152             }
153         }
154 
155         public boolean isDefault() {
156             return (value == defaultvalue);
157         }
158 
159         public Modifier.Iterator getIterator(TestEnvironment env) {
160             return new BooleanIterator(valuelist[value]);
161         }
162 
163         public JComponent getJComponent() {
164             if (jp == null) {
165                 jp = new JPanel();
166                 jp.setLayout(new BorderLayout());
167                 JLabel jl = new JLabel(getDescription());
168                 jp.add(jl, BorderLayout.WEST);
169                 jcb = new JComboBox(valnames);
170                 updateGUI();
171                 jcb.addItemListener(new ItemListener() {
172                     public void itemStateChanged(ItemEvent e) {
173                         if (e.getStateChange() == ItemEvent.SELECTED) {
174                             JComboBox jcb = (JComboBox) e.getItemSelectable();
175                             value = jcb.getSelectedIndex();
176                             if (J2DBench.verbose.isEnabled()) {
177                                 System.out.println(getOptionString());
178                             }
179                         }
180                     }
181                 });
182                 jp.add(jcb, BorderLayout.EAST);
183             }
184             return jp;
185         }
186 
187         public String getAbbreviatedModifierDescription(Object value) {
188             String ret = getNodeName();
189             if (value.equals(Boolean.FALSE)) {
190                 ret = "!"+ret;
191             }
192             return ret;
193         }
194 
195         public String getValString() {
196             return valnames[value];
197         }
198 
199         public String setValueFromString(String value) {
200             for (int i = 0; i < valnames.length; i++) {
201                 if (valnames[i].equalsIgnoreCase(value)) {
202                     if (this.value != i) {
203                         this.value = i;
204                         updateGUI();
205                     }
206                     return null;
207                 }
208             }
209             return "Bad value";
210         }
211     }
212 
213     public static class Enable extends Option {
214         boolean defaultvalue;
215         boolean value;
216         JCheckBox jcb;
217 
218         public Enable(Group parent, String nodeName, String description,
219                       boolean defaultvalue)
220         {
221             super(parent, nodeName, description);
222             this.defaultvalue = this.value = defaultvalue;
223         }
224 
225         public boolean isEnabled() {
226             return value;
227         }
228 
229         public void modifyTest(TestEnvironment env) {
230             // Used from within a Group.EnableSet group.
231         }
232 
233         public void restoreTest(TestEnvironment env) {
234             // Used from within a Group.EnableSet group.
235         }
236 
237         public void restoreDefault() {
238             if (value != defaultvalue) {
239                 value = defaultvalue;
240                 updateGUI();
241             }
242         }
243 
244         public void updateGUI() {
245             if (jcb != null) {
246                 jcb.setSelected(value);
247             }
248         }
249 
250         public boolean isDefault() {
251             return (value == defaultvalue);
252         }
253 
254         public Modifier.Iterator getIterator(TestEnvironment env) {
255             return new BooleanIterator(value);
256         }
257 
258         public JComponent getJComponent() {
259             if (jcb == null) {
260                 jcb = new JCheckBox(getDescription());
261                 updateGUI();
262                 jcb.addItemListener(new ItemListener() {
263                     public void itemStateChanged(ItemEvent e) {
264                         value = (e.getStateChange() == ItemEvent.SELECTED);
265                         if (J2DBench.verbose.isEnabled()) {
266                             System.out.println(getOptionString());
267                         }
268                     }
269                 });
270             }
271             return jcb;
272         }
273 
274         public String getAbbreviatedModifierDescription(Object value) {
275             String ret = getNodeName();
276             if (value.equals(Boolean.FALSE)) {
277                 ret = "!"+ret;
278             }
279             return ret;
280         }
281 
282         public String getValString() {
283             return (value ? "enabled" : "disabled");
284         }
285 
286         public String setValueFromString(String value) {
287             boolean newval;
288             if (value.equalsIgnoreCase("enabled")) {
289                 newval = true;
290             } else if (value.equalsIgnoreCase("disabled")) {
291                 newval = false;
292             } else {
293                 return "Bad Value";
294             }
295             if (this.value != newval) {
296                 this.value = newval;
297                 updateGUI();
298             }
299             return null;
300         }
301     }
302 
303     public static class Int extends Option {
304         int minvalue;
305         int maxvalue;
306         int defaultvalue;
307         int value;
308         JPanel jp;
309         JTextField jtf;
310 
311         public Int(Group parent, String nodeName, String description,
312                    int minvalue, int maxvalue, int defaultvalue)
313         {
314             super(parent, nodeName, description);
315             this.minvalue = minvalue;
316             this.maxvalue = maxvalue;
317             if (defaultvalue < minvalue || defaultvalue > maxvalue) {
318                 throw new RuntimeException("bad value string: "+value);
319             }
320             this.defaultvalue = this.value = defaultvalue;
321         }
322 
323         public int getIntValue() {
324             return value;
325         }
326 
327         public void restoreDefault() {
328             if (value != defaultvalue) {
329                 value = defaultvalue;
330                 updateGUI();
331             }
332         }
333 
334         public void updateGUI() {
335             if (jtf != null) {
336                 jtf.setText(getValString());
337             }
338         }
339 
340         public boolean isDefault() {
341             return (value == defaultvalue);
342         }
343 
344         public Modifier.Iterator getIterator(TestEnvironment env) {
345             return new SwitchIterator(new Object[] { new Integer(value) }, 1);
346         }
347 
348         public JComponent getJComponent() {
349             if (jp == null) {
350                 jp = new JPanel();
351                 jp.setLayout(new BorderLayout());
352                 jp.add(new JLabel(getDescription()), BorderLayout.WEST);
353                 jtf = new JTextField(10);
354                 updateGUI();
355                 jtf.setDocument(new PlainDocument() {
356                     public void insertString(int offs, String str,
357                                              AttributeSet a)
358                         throws BadLocationException
359                     {
360                         if (str == null) {
361                             return;
362                         }
363                         for (int i = 0; i < str.length(); i++) {
364                             char c = str.charAt(i);
365                             if (c < '0' || c > '9') {
366                                 Toolkit.getDefaultToolkit().beep();
367                                 return;
368                             }
369                         }
370                         String oldstr = jtf.getText();
371                         super.insertString(offs, str, a);
372                         str = jtf.getText();
373                         if (setValueFromString(str) == null) {
374                             if (J2DBench.verbose.isEnabled()) {
375                                 System.out.println(getOptionString());
376                             }
377                         } else {
378                             super.remove(0, super.getLength());
379                             super.insertString(0, oldstr, null);
380                             Toolkit.getDefaultToolkit().beep();
381                         }
382                     }
383                 });
384                 jtf.setText(getValString());
385                 jp.add(jtf, BorderLayout.EAST);
386             }
387             return jp;
388         }
389 
390         public String getValString() {
391             return Integer.toString(value);
392         }
393 
394         public String setValueFromString(String value) {
395             int val;
396             try {
397                 val = Integer.parseInt(value);
398             } catch (NumberFormatException e) {
399                 return "Value not an integer ("+value+")";
400             }
401             if (val < minvalue || val > maxvalue) {
402                 return "Value out of range";
403             }
404             if (this.value != val) {
405                 this.value = val;
406                 updateGUI();
407             }
408             return null;
409         }
410     }
411 
412     public static class ObjectList extends Option {
413         int size;
414         String optionnames[];
415         Object optionvalues[];
416         String abbrevnames[];
417         String descnames[];
418         int defaultenabled;
419         int enabled;
420         JPanel jp;
421         JList jlist;
422         int numrows;
423 
424         public ObjectList(Group parent, String nodeName, String description,
425                           String optionnames[],
426                           Object optionvalues[],
427                           String abbrevnames[],
428                           String descnames[],
429                           int defaultenabled)
430         {
431             this(parent, nodeName, description,
432                  Math.min(Math.min(optionnames.length,
433                                    optionvalues.length),
434                           Math.min(abbrevnames.length,
435                                    descnames.length)),
436                  optionnames, optionvalues,
437                  abbrevnames, descnames, defaultenabled);
438         }
439 
440         public ObjectList(Group parent, String nodeName, String description,
441                           int size,
442                           String optionnames[],
443                           Object optionvalues[],
444                           String abbrevnames[],
445                           String descnames[],
446                           int defaultenabled)
447         {
448             super(parent, nodeName, description);
449             this.size = size;
450             this.optionnames = trim(optionnames, size);
451             this.optionvalues = trim(optionvalues, size);
452             this.abbrevnames = trim(abbrevnames, size);
453             this.descnames = trim(descnames, size);
454             this.enabled = this.defaultenabled = defaultenabled;
455         }
456 
457         private static String[] trim(String list[], int size) {
458             if (list.length == size) {
459                 return list;
460             }
461             String newlist[] = new String[size];
462             System.arraycopy(list, 0, newlist, 0, size);
463             return newlist;
464         }
465 
466         private static Object[] trim(Object list[], int size) {
467             if (list.length == size) {
468                 return list;
469             }
470             Object newlist[] = new Object[size];
471             System.arraycopy(list, 0, newlist, 0, size);
472             return newlist;
473         }
474 
475         public void restoreDefault() {
476             if (enabled != defaultenabled) {
477                 enabled = defaultenabled;
478                 updateGUI();
479             }
480         }
481 
482         public void updateGUI() {
483             if (jlist != null) {
484                 int enabled = this.enabled;
485                 jlist.clearSelection();
486                 for (int curindex = 0; curindex < size; curindex++) {
487                     if ((enabled & (1 << curindex)) != 0) {
488                         jlist.addSelectionInterval(curindex, curindex);
489                     }
490                 }
491             }
492         }
493 
494         public boolean isDefault() {
495             return (enabled == defaultenabled);
496         }
497 
498         public Modifier.Iterator getIterator(TestEnvironment env) {
499             return new SwitchIterator(optionvalues, enabled);
500         }
501 
502         public void setNumRows(int numrows) {
503             this.numrows = numrows;
504         }
505 
506         public JComponent getJComponent() {
507             if (jp == null) {
508                 jp = new JPanel();
509                 jp.setLayout(new BorderLayout());
510                 jp.add(new JLabel(getDescription()), BorderLayout.WEST);
511                 jlist = new JList(descnames);
512                 if (numrows > 0) {
513                     try {
514                         jlist.setLayoutOrientation(JList.VERTICAL_WRAP);
515                     } catch (NoSuchMethodError e) {
516                     }
517                     jlist.setVisibleRowCount(numrows);
518                 }
519                 jlist.setBorder(new LineBorder(Color.black, 2));
520                 updateGUI();
521                 jlist.addListSelectionListener(new ListSelectionListener() {
522                     public void valueChanged(ListSelectionEvent e) {
523                         int flags = 0;
524                         for (int curindex = 0; curindex < size; curindex++) {
525                             JList list = (JList) e.getSource();
526                             if (list.isSelectedIndex(curindex)) {
527                                 flags |= (1 << curindex);
528                             }
529                         }
530                         enabled = flags;
531                         if (J2DBench.verbose.isEnabled()) {
532                             System.out.println(getOptionString());
533                         }
534                     }
535                 });
536                 jp.add(jlist, BorderLayout.EAST);
537             }
538             return jp;
539         }
540 
541         public String getValString() {
542             StringBuffer sb = new StringBuffer();
543             for (int i = 0; i < size; i++) {
544                 if ((enabled & (1 << i)) != 0) {
545                     if (sb.length() > 0) {
546                         sb.append(',');
547                     }
548                     sb.append(optionnames[i]);
549                 }
550             }
551             return sb.toString();
552         }
553 
554         int findValueIndex(Object value) {
555             for (int i = 0; i < size; i++) {
556                 if (optionvalues[i] == value) {
557                     return i;
558                 }
559             }
560             return -1;
561         }
562 
563         public String getValString(Object value) {
564             return optionnames[findValueIndex(value)];
565         }
566 
567         public String getAbbreviatedModifierDescription(Object value) {
568             return abbrevnames[findValueIndex(value)];
569         }
570 
571         public String setValueFromString(String value) {
572             int enabled = 0;
573             StringTokenizer st = new StringTokenizer(value, ",");
574             while (st.hasMoreTokens()) {
575                 String s = st.nextToken();
576                 try {
577                     for (int i = 0; i < size; i++) {
578                         if (optionnames[i].equals(s)) {
579                             enabled |= (1 << i);
580                             s = null;
581                             break;
582                         }
583                     }
584                 } catch (NumberFormatException e) {
585                 }
586                 if (s != null) {
587                     return "Bad value in list ("+s+")";
588                 }
589             }
590             this.enabled = enabled;
591             updateGUI();
592             return null;
593         }
594     }
595 
596     public static class IntList extends ObjectList {
597         public IntList(Group parent, String nodeName, String description,
598                        int values[], String abbrevnames[], String descnames[],
599                        int defaultenabled)
600         {
601             super(parent, nodeName, description,
602                   makeNames(values), makeValues(values),
603                   abbrevnames, descnames, defaultenabled);
604         }
605 
606         private static String[] makeNames(int intvalues[]) {
607             String names[] = new String[intvalues.length];
608             for (int i = 0; i < intvalues.length; i++) {
609                 names[i] = Integer.toString(intvalues[i]);
610             }
611             return names;
612         }
613 
614         private static Object[] makeValues(int intvalues[]) {
615             Object values[] = new Object[intvalues.length];
616             for (int i = 0; i < intvalues.length; i++) {
617                 values[i] = new Integer(intvalues[i]);
618             }
619             return values;
620         }
621     }
622 
623     public static class ObjectChoice extends Option {
624          int size;
625          String optionnames[];
626          Object optionvalues[];
627          String abbrevnames[];
628          String descnames[];
629          int defaultselected;
630          int selected;
631          JPanel jp;
632          JComboBox jcombo;
633 
634          public ObjectChoice(Group parent, String nodeName, String description,
635                              String optionnames[],
636                              Object optionvalues[],
637                              String abbrevnames[],
638                              String descnames[],
639                              int defaultselected)
640          {
641              this(parent, nodeName, description,
642                   Math.min(Math.min(optionnames.length,
643                                     optionvalues.length),
644                            Math.min(abbrevnames.length,
645                                     descnames.length)),
646                   optionnames, optionvalues,
647                   abbrevnames, descnames, defaultselected);
648          }
649 
650          public ObjectChoice(Group parent, String nodeName, String description,
651                              int size,
652                              String optionnames[],
653                              Object optionvalues[],
654                              String abbrevnames[],
655                              String descnames[],
656                              int defaultselected)
657          {
658              super(parent, nodeName, description);
659              this.size = size;
660              this.optionnames = trim(optionnames, size);
661              this.optionvalues = trim(optionvalues, size);
662              this.abbrevnames = trim(abbrevnames, size);
663              this.descnames = trim(descnames, size);
664              this.selected = this.defaultselected = defaultselected;
665          }
666 
667          private static String[] trim(String list[], int size) {
668              if (list.length == size) {
669                  return list;
670              }
671              String newlist[] = new String[size];
672              System.arraycopy(list, 0, newlist, 0, size);
673              return newlist;
674          }
675 
676          private static Object[] trim(Object list[], int size) {
677              if (list.length == size) {
678                  return list;
679              }
680              Object newlist[] = new Object[size];
681              System.arraycopy(list, 0, newlist, 0, size);
682              return newlist;
683          }
684 
685          public void restoreDefault() {
686              if (selected != defaultselected) {
687                  selected = defaultselected;
688                  updateGUI();
689              }
690          }
691 
692          public void updateGUI() {
693              if (jcombo != null) {
694                  jcombo.setSelectedIndex(this.selected);
695              }
696          }
697 
698          public boolean isDefault() {
699              return (selected == defaultselected);
700          }
701 
702          public Modifier.Iterator getIterator(TestEnvironment env) {
703              return new SwitchIterator(optionvalues, 1 << selected);
704          }
705 
706          public JComponent getJComponent() {
707              if (jp == null) {
708                  jp = new JPanel();
709                  jp.setLayout(new BorderLayout());
710                  jp.add(new JLabel(getDescription()), BorderLayout.WEST);
711                  jcombo = new JComboBox(descnames);
712                  updateGUI();
713                  jcombo.addItemListener(new ItemListener() {
714                      public void itemStateChanged(ItemEvent e) {
715                          if (e.getStateChange() == ItemEvent.SELECTED) {
716                              selected = jcombo.getSelectedIndex();
717                              if (J2DBench.verbose.isEnabled()) {
718                                  System.out.println(getOptionString());
719                              }
720                          }
721                      }
722                  });
723                  jp.add(jcombo, BorderLayout.EAST);
724              }
725              return jp;
726          }
727 
728          public Object getValue() {
729              return optionvalues[selected];
730          }
731 
732          public int getIntValue() {
733              return ((Integer) optionvalues[selected]).intValue();
734          }
735 
736          public boolean getBooleanValue() {
737              return ((Boolean) optionvalues[selected]).booleanValue();
738          }
739 
740          public String getValString() {
741              return optionnames[selected];
742          }
743 
744          int findValueIndex(Object value) {
745              for (int i = 0; i < size; i++) {
746                  if (optionvalues[i] == value) {
747                      return i;
748                  }
749              }
750              return -1;
751          }
752 
753          public String getValString(Object value) {
754              return optionnames[findValueIndex(value)];
755          }
756 
757          public String getAbbreviatedModifierDescription(Object value) {
758              return abbrevnames[findValueIndex(value)];
759          }
760 
761          public String setValue(int v) {
762              return setValue(new Integer(v));
763          }
764 
765          public String setValue(boolean v) {
766              return setValue(new Boolean(v));
767          }
768 
769          public String setValue(Object value) {
770              for (int i = 0; i < size; i++) {
771                  if (optionvalues[i].equals(value)) {
772                      this.selected = i;
773                      updateGUI();
774                      return null;
775                  }
776              }
777              return "Bad value";
778          }
779 
780          public String setValueFromString(String value) {
781              for (int i = 0; i < size; i++) {
782                  if (optionnames[i].equals(value)) {
783                      this.selected = i;
784                      updateGUI();
785                      return null;
786                  }
787              }
788              return "Bad value";
789          }
790     }
791 
792     public static class BooleanIterator implements Modifier.Iterator {
793         private Boolean list[];
794         private int index;
795 
796         public static final Boolean FalseList[] = { Boolean.FALSE };
797         public static final Boolean TrueList[] = { Boolean.TRUE };
798         public static final Boolean
799             FalseTrueList[] = { Boolean.FALSE, Boolean.TRUE };
800         public static final Boolean
801             TrueFalseList[] = { Boolean.TRUE, Boolean.FALSE };
802 
803         public BooleanIterator(boolean v) {
804             this(v ? TrueList : FalseList);
805         }
806 
807         public BooleanIterator(Boolean list[]) {
808             this.list = list;
809         }
810 
811         public boolean hasNext() {
812             return (index < list.length);
813         }
814 
815         public Object next() {
816             if (index >= list.length) {
817                 throw new NoSuchElementException();
818             }
819             return list[index++];
820         }
821 
822         public void remove() {
823             throw new UnsupportedOperationException();
824         }
825     }
826 
827     public static class SwitchIterator implements Modifier.Iterator {
828         private Object list[];
829         private int enabled;
830         private int index;
831 
832         public SwitchIterator(Object[] list, int enabled) {
833             this.list = list;
834             this.enabled = enabled;
835         }
836 
837         public boolean hasNext() {
838             return ((1 << index) <= enabled);
839         }
840 
841         public Object next() {
842             while ((enabled & (1 << index)) == 0) {
843                 index++;
844                 if (index >= list.length) {
845                     throw new NoSuchElementException();
846                 }
847             }
848             return list[index++];
849         }
850 
851         public void remove() {
852             throw new UnsupportedOperationException();
853         }
854     }
855 }